package com.xjrsoft.module.workflow.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.core.tool.utils.BeanUtil;
import com.xjrsoft.core.tool.utils.FlowableUtil;
import com.xjrsoft.core.tool.utils.StringPool;
import com.xjrsoft.core.tool.utils.StringUtil;
import com.xjrsoft.module.base.entity.XjrBaseTempfield;
import com.xjrsoft.module.base.entity.XjrBaseUser;
import com.xjrsoft.module.base.service.IXjrBaseTempfieldService;
import com.xjrsoft.module.base.service.IXjrBaseUserService;
import com.xjrsoft.module.base.utils.OrganizationCacheUtil;
import com.xjrsoft.module.base.vo.UserVo;
import com.xjrsoft.module.workflow.dto.GetPageListNwfMonitorDto;
import com.xjrsoft.module.workflow.mapper.NwfMonitorMapper;
import com.xjrsoft.module.workflow.service.IXjrNwfMonitorService;
import com.xjrsoft.module.workflow.vo.TaskVo;
import io.jsonwebtoken.lang.Collections;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;

@Slf4j
@Service
@AllArgsConstructor
public class XjrNwfMonitorServiceImpl implements IXjrNwfMonitorService {

    private TaskService taskService;

    private HistoryService historyService;

    private RuntimeService runtimeService;

    private NwfMonitorMapper nwfMonitorMapper;

    private IXjrBaseUserService userService;

    private IXjrBaseTempfieldService xjrBaseTempfieldService;

    private RepositoryService repositoryService;

    @Override
    public PageOutput finishedProcess(GetPageListNwfMonitorDto dto) {
        log.info("【完成的流程查询】");
        JSONArray retArray = new JSONArray();
        Page page = nwfMonitorMapper.finishedProcess(new Page(dto.getLimit(), dto.getSize()), dto.getStartTime(), dto.getEndTime(), StringPool.PERCENT + dto.getKeyword() + StringPool.PERCENT);
        List<TaskVo> taskVos = page.getRecords();
        List<XjrBaseUser> listCaches = userService.list();
        HashMap<String, String> map = new HashMap<>();
        for (XjrBaseUser listCach : listCaches) {
            if (listCach != null) {
                map.put(listCach.getUserId(), listCach.getRealName());
            }
        }
        for (TaskVo taskVo : taskVos) {
            String processInstanceId = taskVo.getProcessInstanceId();
            // 获取任务名称
            List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).orderByHistoricTaskInstanceEndTime().desc().list();
            List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().desc().list();
            if (list != null && list.size() > 0) {
                HistoricTaskInstance historicTaskInstance = list.get(0);
                String taskId = historicTaskInstance.getId();
                JSONObject taskCandidateUser = FlowableUtil.getTaskCandidateUser(processInstanceId);
                JSONArray candidateUsers = taskCandidateUser.getJSONArray("candidateUsers");
                ArrayList<UserVo> userVos = new ArrayList<>();
                for (Object candidateUser : candidateUsers) {
                    if (candidateUser != null) {
                        UserVo userVo = BeanUtil.copy(candidateUser, UserVo.class);
                        userVos.add(userVo);
                    }
                }
                taskVo.setCandidateUsers(userVos);
                taskVo.setTaskName(historicTaskInstance.getName());
                taskVo.setPriority(historicTaskInstance.getPriority());
                taskVo.setTaskId(taskId);
                taskVo.setSuspended(0);
                retArray.add(taskVo);
            }
            taskVo.setStartUser(map.get(taskVo.getStartUser()));
            taskVo.setCurrentProgress("100");
        }
        return ConventPage.getPageOutput(page);
    }

    @Override
    public PageOutput unfinishedProcess(GetPageListNwfMonitorDto dto) {
        log.info("【未完成的流程查询】");
        List<XjrBaseUser> xjrBaseUserlist = OrganizationCacheUtil.getListCaches(OrganizationCacheUtil.USER_LIST_CACHE_KEY);
        JSONArray retArray = new JSONArray();
        Page<TaskVo> page = nwfMonitorMapper.unfinishedProcess(new Page(dto.getLimit(), dto.getSize()), dto.getStartTime(), dto.getEndTime(), StringPool.PERCENT + dto.getKeyword() + StringPool.PERCENT);
        List<XjrBaseTempfield> callActivityTempList = xjrBaseTempfieldService.list(new QueryWrapper<XjrBaseTempfield>().lambda().eq(XjrBaseTempfield::getType, "34"));
        List<TaskVo> taskVos = page.getRecords();
        for (TaskVo taskVo : taskVos) {
            String processInstanceId = taskVo.getProcessInstanceId();
            List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().desc().list();
            HistoricActivityInstance historicActivityInstance = historicActivityInstanceList.get(0);
            // 获取任务名称
            List<HistoricTaskInstance> historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery().orderByHistoricTaskInstanceStartTime().desc().processInstanceId(processInstanceId).list();
            if (!Collections.isEmpty(historicTaskInstanceList)) {
                HistoricTaskInstance historicTaskInstance = historicTaskInstanceList.get(0);
                // 任务审批人
                String id = historicTaskInstance.getAssignee();
                if (id != null) {
                    XjrBaseUser xjrBaseUser = new XjrBaseUser();
                    Optional<XjrBaseUser> xjrBaseUserOptional = xjrBaseUserlist.stream().filter(x -> x.getUserId().equals(id)).findFirst();
                    if (xjrBaseUserOptional.isPresent()) {
                        xjrBaseUser = xjrBaseUserOptional.get();
                    }
                    if (xjrBaseUser != null) {
                        List<UserVo> userArray = new ArrayList<>();
                        userArray.add(BeanUtil.copy(xjrBaseUser, UserVo.class));
                        taskVo.setCandidateUsers(userArray);
                    } else {
                        JSONObject taskCandidateUser = FlowableUtil.getTaskCandidateUser(processInstanceId);
                        JSONArray candidateUsers = taskCandidateUser.getJSONArray("candidateUsers");
                        ArrayList<UserVo> userVos = new ArrayList<>();
                        for (Object candidateUser : candidateUsers) {
                            if (candidateUser != null) {
                                UserVo userVo = BeanUtil.copy(candidateUser, UserVo.class);
                                userVos.add(userVo);
                            }
                        }
                        taskVo.setCandidateUsers(userVos);
                    }
                }
                // 流程发起人
                Optional<XjrBaseUser> xjrBaseUserOptional = xjrBaseUserlist.stream().filter(x -> x.getUserId().equals(taskVo.getStartUser())).findFirst();
                XjrBaseUser startUser = new XjrBaseUser();
                if (xjrBaseUserOptional.isPresent()) {
                    startUser = xjrBaseUserOptional.get();
                }
                if (startUser != null) {
                    taskVo.setStartUser(startUser.getRealName());
                }
                taskVo.setTaskName(historicTaskInstance.getName());
                taskVo.setPriority(historicTaskInstance.getPriority());
                taskVo.setTaskId(historicTaskInstance.getId());
                Execution execution = runtimeService.createExecutionQuery().executionId(historicTaskInstance.getExecutionId()).processInstanceId(processInstanceId).singleResult();
                if (execution != null) {
                    boolean suspended = execution.isSuspended();
                    XjrBaseTempfield xjrBaseTempfield = xjrBaseTempfieldService.getByIdAndType(historicTaskInstance.getProcessInstanceId(), "36");
                    XjrBaseTempfield xjrBaseTempfield1 = xjrBaseTempfieldService.getByIdAndType(historicTaskInstance.getProcessInstanceId(), "33");
                    if (xjrBaseTempfield != null && suspended) {
                        taskVo.setSuspended(2);
                        //添加挂起原因
                        taskVo.setSuspendedCause(xjrBaseTempfield.getFvalue());
                    } else if (xjrBaseTempfield1 != null && suspended) {
                        String fvalue = xjrBaseTempfield1.getFvalue();
                        //兼容之前的数据
                        taskVo.setSuspended(StringUtil.equalsIgnoreCase(fvalue, "流程被暂停") ? 2 : 1);
                        //添加挂起原因
                        taskVo.setSuspendedCause(StringUtil.equalsIgnoreCase(fvalue, "流程被暂停") ? "流程被挂起" : fvalue);
                    } else {
                        taskVo.setSuspended(0);
                    }
                }
                if (taskVo.getEndTime() != null) {
                    taskVo.setCurrentProgress("100");
                } else if (StringUtil.equals(historicActivityInstance.getActivityType(), "callActivity")) {
                    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(taskVo.getDeploymentId()).singleResult();
                    String version = String.valueOf(processDefinition.getVersion());
                    String nwfSchemeInfoId = processDefinition.getDescription();
                    String key = nwfSchemeInfoId + StringPool.UNDERSCORE + historicActivityInstance.getActivityId() + StringPool.UNDERSCORE + version;
                    Optional<XjrBaseTempfield> xjrBaseTempfieldOptional = callActivityTempList.stream().filter(s -> StringUtil.equals(s.getFkey(), key)).findFirst();
                    if (xjrBaseTempfieldOptional.isPresent()) {
                        String fvalue = xjrBaseTempfieldOptional.get().getFvalue();
                        taskVo.setCurrentProgress(StringUtil.equalsIgnoreCase(fvalue,"null")?null:fvalue);
                    }else {
                        taskVo.setCurrentProgress(null);
                    }
                    taskVo.setTaskName(historicActivityInstance.getActivityName());
                } else {
                    taskVo.setCurrentProgress(historicTaskInstance.getDescription());
                }
                retArray.add(taskVo);
            }
        }
        return ConventPage.getPageOutput(page);
    }
}
